package etcd

import (
	"ydd-im/service/api/define"
	"context"

	"github.com/coreos/etcd/clientv3"
	"github.com/coreos/etcd/mvcc/mvccpb"
	log "github.com/sirupsen/logrus"
	"strings"
	"time"
)

type ClientDis struct {
	client *clientv3.Client
}

func NewClientDis(addr []string) (*ClientDis, error) {
	// 初始化slice
	define.ServerList = make(map[string]string)
	define.AccountServerList = make(map[string]string)
	define.DbproxyServerList = make(map[string]string)
	define.GroupServerList = make(map[string]string)
	conf := clientv3.Config{
		Endpoints:   addr,
		DialTimeout: 5 * time.Second,
	}
	if client, err := clientv3.New(conf); err == nil {
		return &ClientDis{
			client: client,
		}, nil
	} else {
		return nil, err
	}
}

func (this *ClientDis) GetService(prefix string) ([]string, error) {
	resp, err := this.client.Get(context.Background(), prefix, clientv3.WithPrefix())
	if err != nil {
		return nil, err
	}
	addrs := this.extractAddrs(resp,prefix)
	go this.watcher(prefix)
	return addrs, nil
}

func (this *ClientDis) watcher(prefix string) {

	rch := this.client.Watch(context.Background(), prefix, clientv3.WithPrefix())
	for wresp := range rch {
		for _, ev := range wresp.Events {
			switch ev.Type {
			case mvccpb.PUT:
				this.SetEtcdServiceList(string(ev.Kv.Key), string(ev.Kv.Value),prefix)
			case mvccpb.DELETE:
				this.DelEtcdServiceList(string(ev.Kv.Key),prefix)
			}
		}
	}
}

func (this *ClientDis) extractAddrs(resp *clientv3.GetResponse,prefix string) []string {
	addrs := make([]string, 0)
	if resp == nil || resp.Kvs == nil {
		return addrs
	}
	for i := range resp.Kvs {
		if v := resp.Kvs[i].Value; v != nil {
			this.SetEtcdServiceList(string(resp.Kvs[i].Key), string(resp.Kvs[i].Value),prefix)
			addrs = append(addrs, string(v))
		}
	}

	return addrs
}
// 添加主服务，api
func (this *ClientDis) SetServiceList(key, val string) {
	define.ServerListLock.Lock()
	defer define.ServerListLock.Unlock()
	define.ServerList[key] = val
	log.Info("发现服务api：", key, " 地址:", val)
}
// 删除主服务，api
func (this *ClientDis) DelServiceList(key string) {
	define.ServerListLock.Lock()
	defer define.ServerListLock.Unlock()
	delete(define.ServerList, key)
	log.Println("服务下线api:", key)
}
// 添加账号服务，account
func (this *ClientDis) SetAccountServiceList(key, val string) {
	define.AccountServerListLock.Lock()
	defer define.AccountServerListLock.Unlock()
	define.AccountServerList[key] = val
	log.Info("发现服务Account：", key, " 地址:", val)
}
// 删除账号服务，account
func (this *ClientDis) DelAccountServiceList(key string) {
	define.AccountServerListLock.Lock()
	defer define.AccountServerListLock.Unlock()
	delete(define.AccountServerList, key)
	log.Println("服务Account下线:", key)
}

// 添加数据库服务，dbproxy
func (this *ClientDis) SetDbproxyServiceList(key, val string) {
	define.DbproxyServerListLock.Lock()
	defer define.DbproxyServerListLock.Unlock()
	define.DbproxyServerList[key] = val
	log.Info("发现服务Dbproxy：", key, " 地址:", val)
}
// 删除数据库服务，dbproxy
func (this *ClientDis) DelDbproxyServiceList(key string) {
	define.DbproxyServerListLock.Lock()
	defer define.DbproxyServerListLock.Unlock()
	delete(define.DbproxyServerList, key)
	log.Println("服务Dbproxy下线:", key)
}


// 添加群服务，group
func (this *ClientDis) SetEtcdServiceList(key, val,prefix string) {
	if strings.EqualFold(prefix, define.ETCD_SERVER_Account_LIST)  {
		define.AccountServerListLock.Lock()
		defer define.AccountServerListLock.Unlock()
		define.AccountServerList[key] = val
		log.Info("发现服务Account：", key, " 地址:", val)
	}else if strings.EqualFold(prefix, define.ETCD_SERVER_Dbproxy_LIST)  {
		define.DbproxyServerListLock.Lock()
		defer define.DbproxyServerListLock.Unlock()
		define.DbproxyServerList[key] = val
		log.Info("发现服务Dbproxy：", key, " 地址:", val)
	} else if strings.EqualFold(prefix, define.ETCD_SERVER_Group_LIST)  {
		define.GroupServerListLock.Lock()
		defer define.GroupServerListLock.Unlock()
		define.GroupServerList[key] = val
		log.Info("发现服务Group：", key, " 地址:", val)
	}else{
		define.ServerListLock.Lock()
		defer define.ServerListLock.Unlock()
		define.ServerList[key] = val
		log.Info("发现服务api：", key, " 地址:", val)
	}

}
// 删除服务
func (this *ClientDis) DelEtcdServiceList(key string,prefix string) {
	if strings.EqualFold(prefix, define.ETCD_SERVER_Account_LIST)  {
		define.AccountServerListLock.Lock()
		defer define.AccountServerListLock.Unlock()
		delete(define.AccountServerList, key)
		log.Println("服务Account下线:", key)

	}else if strings.EqualFold(prefix, define.ETCD_SERVER_Dbproxy_LIST)  {
		define.DbproxyServerListLock.Lock()
		defer define.DbproxyServerListLock.Unlock()
		delete(define.DbproxyServerList, key)
		log.Println("服务Dbproxy下线:", key)
	} else if strings.EqualFold(prefix, define.ETCD_SERVER_Group_LIST)  {
		define.GroupServerListLock.Lock()
		defer define.GroupServerListLock.Unlock()
		delete(define.GroupServerList, key)
		log.Println("服务group下线:", key)
	}else{
		define.ServerListLock.Lock()
		defer define.ServerListLock.Unlock()
		delete(define.ServerList, key)
		log.Println("服务下线api:", key)
	}
}